package com.ssy.lingxi.order.serviceimpl.base;

import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.order.entity.OrderTradeProcessContractDO;
import com.ssy.lingxi.order.entity.OrderTradeProcessDO;
import com.ssy.lingxi.order.model.vo.process.request.OrderTradeProcessContractVO;
import com.ssy.lingxi.order.model.vo.process.response.OrderTradeProcessContractDetailVO;
import com.ssy.lingxi.order.repository.OrderTradeProcessContractRepository;
import com.ssy.lingxi.order.service.base.IBaseOrderTradeProcessContractService;
import com.ssy.lingxi.order.utils.NumberUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;

/**
 * 交易规则关联的合同相关接口实现类
 * @author 万宁
 * @version 2.0.0
 * @date 2021-07-24
 */
@Service
public class BaseOrderTradeProcessContractServiceImpl implements IBaseOrderTradeProcessContractService {
    @Resource
    private OrderTradeProcessContractRepository orderTradeProcessContractRepository;

    /**
     * 新增、修改交易规则配置时，校验合同信息
     *
     * @param hasContract    是否使用合同
     * @param contractVO     合同信息
     * @return 检查结果
     */
    @Override
    public Wrapper<Void> checkContract(Boolean hasContract, OrderTradeProcessContractVO contractVO) {
        //检查参数
        if(hasContract && (contractVO == null || NumberUtil.isNullOrZero(contractVO.getContractId()))) {
            return Wrapper.fail(ResponseCode.ORDER_TRADE_PROCESS_CONTRACT_CAN_NOT_BE_EMPTY);
        }

        //不需要校验合同是否存在于另一个相同的配置中
        return Wrapper.success();
    }

    /**
     * 保存交易规则关联的合同信息，调用方要保存OrderTradeProcessDO
     *
     * @param tradeProcess 交易流程规则
     * @param hasContract  是否使用电子合同
     * @param contractVO   电子合同信息
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public void saveContract(OrderTradeProcessDO tradeProcess, Boolean hasContract, OrderTradeProcessContractVO contractVO) {
        if(!hasContract) {
            tradeProcess.setContract(null);
            return;
        }

        OrderTradeProcessContractDO contract = new OrderTradeProcessContractDO();
        contract.setContractId(contractVO.getContractId());
        contract.setContractName(StringUtils.hasLength(contractVO.getContractName()) ? contractVO.getContractName().trim() : "");
        contract.setProcess(tradeProcess);
        orderTradeProcessContractRepository.saveAndFlush(contract);

        tradeProcess.setContract(contract);
    }

    /**
     * 查询交易流程规则关联的合同信息
     *
     * @param tradeProcess 交易流程规则
     * @return 合同信息
     */
    @Override
    public OrderTradeProcessContractDetailVO getContract(OrderTradeProcessDO tradeProcess) {
        if(!tradeProcess.getHasContract()) {
            return null;
        }

        OrderTradeProcessContractDO contract = orderTradeProcessContractRepository.findFirstByProcess(tradeProcess);
        if(contract == null) {
            return null;
        }

        OrderTradeProcessContractDetailVO detailVO = new OrderTradeProcessContractDetailVO();
        detailVO.setContractId(contract.getContractId());
        detailVO.setContractName(contract.getContractName());

        return detailVO;
    }

    /**
     * 更新交易规则关联的合同信息，调用方要保存OrderTradeProcessDO
     *
     * @param tradeProcess 交易流程规则
     * @param hasContract  是否使用电子合同
     * @param contractVO   电子合同信息
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public void updateContract(OrderTradeProcessDO tradeProcess, Boolean hasContract, OrderTradeProcessContractVO contractVO) {
        if(!hasContract) {
            orderTradeProcessContractRepository.deleteByProcess(tradeProcess);
            tradeProcess.setContract(null);
            return;
        }

        OrderTradeProcessContractDO contract = orderTradeProcessContractRepository.findFirstByProcess(tradeProcess);
        if(contract == null) {
            contract = new OrderTradeProcessContractDO();
        }

        contract.setProcess(tradeProcess);
        contract.setContractId(contractVO.getContractId());
        contract.setContractName(contractVO.getContractName());
        orderTradeProcessContractRepository.saveAndFlush(contract);

        tradeProcess.setContract(contract);
    }
}
